home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / hack.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  39KB  |  1,614 lines

  1. /*    SCCS Id: @(#)hack.c    3.1    92/12/04    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. STATIC_DCL int NDECL(moverock);
  8. #ifdef POLYSELF
  9. STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
  10. #endif
  11. #ifdef SINKS
  12. STATIC_DCL void NDECL(dosinkfall);
  13. #endif
  14. STATIC_DCL boolean FDECL(bad_rock,(XCHAR_P,XCHAR_P));
  15. STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int));
  16.  
  17. static void FDECL(move_update, (BOOLEAN_P));
  18.  
  19. #define IS_SHOP(x)    (rooms[x].rtype >= SHOPBASE)
  20.  
  21. #ifdef OVL2
  22.  
  23. boolean
  24. revive_nasty(x, y, msg)
  25. int x,y;
  26. const char *msg;
  27. {
  28.     register struct obj *otmp, *otmp2;
  29.     struct monst *mtmp;
  30.     coord cc;
  31.     boolean revived = FALSE;
  32.  
  33.     /* prevent freeobj() of revivable corpses */
  34.     for(otmp = level.objects[x][y]; otmp; otmp = otmp2) {
  35.     otmp2 = otmp->nexthere;
  36.     if (otmp->otyp == CORPSE &&
  37.         (is_rider(&mons[otmp->corpsenm]) ||
  38.          otmp->corpsenm == PM_WIZARD_OF_YENDOR)) {
  39.         /* move any living monster already at that location */
  40.         if((mtmp = m_at(x,y)) && enexto(&cc, x, y, mtmp->data))
  41.         rloc_to(mtmp, cc.x, cc.y);
  42.         if(msg) Norep("%s", msg);
  43.         revive_corpse(otmp, 0, FALSE);
  44.         revived = MON_AT(x,y);
  45.     }
  46.     }
  47.  
  48.     /* this location might not be safe, if not, move revived monster */
  49.     if (revived) {
  50.     mtmp = m_at(x,y);
  51.     if (mtmp && !goodpos(x, y, mtmp, mtmp->data) &&
  52.         enexto(&cc, x, y, mtmp->data)) {
  53.         rloc_to(mtmp, cc.x, cc.y);
  54.     }
  55.     /* else impossible? */
  56.     }
  57.  
  58.     return (revived);
  59. }
  60.  
  61. STATIC_OVL int
  62. moverock()
  63. {
  64.     register xchar rx, ry;
  65.     register struct obj *otmp, *otmp2;
  66.     register struct trap *ttmp;
  67.     register struct monst *mtmp;
  68.  
  69.     while ((otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) != 0) {
  70.     rx = u.ux+2*u.dx;
  71.     ry = u.uy+2*u.dy;
  72.     nomul(0);
  73.     if (Levitation || Is_airlevel(&u.uz)) {
  74.         if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
  75.         You("don't have enough leverage to push %s.", the(xname(otmp)));
  76.         /* Give them a chance to climb over it? */
  77.         return -1;
  78.     }
  79. #ifdef POLYSELF
  80.     if (verysmall(uasmon)) {
  81.         if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
  82.         pline("You're too small to push that %s.", xname(otmp));
  83.         goto cannot_push;
  84.     }
  85. #endif
  86.     if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
  87.         (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (
  88. #ifdef REINCARNATION
  89.         !Is_rogue_level(&u.uz) &&
  90. #endif
  91.         (levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) &&
  92.         !sobj_at(BOULDER, rx, ry)) {
  93.         ttmp = t_at(rx, ry);
  94.         mtmp = m_at(rx, ry);
  95.  
  96.         if (revive_nasty(rx, ry, "You sense movement on the other side."))
  97.         return (-1);
  98.  
  99.         if (mtmp && (!mtmp->mtrapped ||
  100.              !(ttmp && ((ttmp->ttyp == PIT) ||
  101.                     (ttmp->ttyp == SPIKED_PIT))))) {
  102.         if (canseemon(mtmp))
  103.             pline("There's %s on the other side.", mon_nam(mtmp));
  104.         else {
  105.             if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy);
  106.             You("hear a monster behind %s.", the(xname(otmp)));
  107.         }
  108.         if (flags.verbose)
  109.             pline("Perhaps that's why you cannot move it.");
  110.         goto cannot_push;
  111.         }
  112.  
  113.         if (ttmp)
  114.         switch(ttmp->ttyp) {
  115.         case SPIKED_PIT:
  116.         case PIT:
  117.             freeobj(otmp);
  118.             if (!flooreffects(otmp, rx, ry, "fall")) {
  119.             place_object(otmp, rx, ry);
  120.             otmp->nobj = fobj;
  121.             fobj = otmp;
  122.             }
  123.             continue;
  124.         case TRAPDOOR:
  125.             pline("%s falls into and plugs a hole in the ground!",
  126.               The(xname(otmp)));
  127.             deltrap(ttmp);
  128.             delobj(otmp);
  129.             delallobj(rx, ry);
  130.             if (cansee(rx,ry)) newsym(rx,ry);
  131.             continue;
  132.         case LEVEL_TELEP:
  133.         case TELEP_TRAP:
  134.             You("push %s and suddenly it disappears!",
  135.             the(xname(otmp)));
  136.             rloco(otmp);
  137.             continue;
  138.         }
  139.         if (closed_door(rx, ry))
  140.         goto nopushmsg;
  141.         if (boulder_hits_pool(otmp, rx, ry, TRUE))
  142.         continue;
  143.         /*
  144.          * Re-link at top of fobj chain so that pile order is preserved
  145.          * when level is restored.
  146.          */
  147.         if (otmp != fobj) {
  148.         otmp2 = fobj;
  149.         while (otmp2->nobj && otmp2->nobj != otmp)
  150.             otmp2 = otmp2->nobj;
  151.         if (!otmp2->nobj) {
  152.             impossible("moverock: error in fobj chain");
  153.         } else {
  154.             otmp2->nobj = otmp->nobj;    
  155.             otmp->nobj = fobj;
  156.             fobj = otmp;
  157.         }
  158.         }
  159.  
  160.         {
  161. #ifdef LINT /* static long lastmovetime; */
  162.         long lastmovetime;
  163.         lastmovetime = 0;
  164. #else
  165.         static long NEARDATA lastmovetime;
  166. #endif
  167.         /* note: this var contains garbage initially and
  168.            after a restore */
  169.         if (moves > lastmovetime+2 || moves < lastmovetime)
  170.             pline("With great effort you move %s.", the(xname(otmp)));
  171.         exercise(A_STR, TRUE);
  172.         lastmovetime = moves;
  173.         }
  174.  
  175.         /* Move the boulder *after* the message. */
  176.         move_object(otmp, rx, ry);
  177.         if (Blind) {
  178.         feel_location(rx,ry);
  179.         feel_location(u.ux+u.dx, u.uy+u.dy);
  180.         } else {
  181.         newsym(rx,ry);
  182.         newsym(u.ux+u.dx, u.uy+u.dy);
  183.         }
  184.     } else {
  185.     nopushmsg:
  186.         You("try to move %s, but in vain.", the(xname(otmp)));
  187.         if (Blind) feel_location(u.ux+u.dx, u.uy+u.dy);
  188.     cannot_push:
  189. #ifdef POLYSELF
  190.         if (throws_rocks(uasmon)) {
  191.         if (!flags.pickup)
  192.             pline("However, you easily can push it aside.");
  193.         else
  194.             pline("However, you easily can pick it up.");
  195.         break;
  196.         }
  197. #endif
  198.         if (((!invent || inv_weight() <= -850) &&
  199.          (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
  200.                      && IS_ROCK(levl[u.ux+u.dx][u.uy].typ))))
  201. #ifdef POLYSELF
  202.         || verysmall(uasmon)
  203. #endif
  204.         ) {
  205.         pline("However, you can squeeze yourself into a small opening.");
  206.         break;
  207.         } else
  208.         return (-1);
  209.     }
  210.     }
  211.     return (0);
  212. }
  213.  
  214. #ifdef POLYSELF
  215. /*
  216.  *  still_chewing()
  217.  *  
  218.  *  Chew on a wall, door, or boulder.  Returns TRUE if still eating, FALSE
  219.  *  when done.
  220.  */
  221. STATIC_OVL int
  222. still_chewing(x,y)
  223.     xchar x, y;
  224. {
  225.     struct rm *lev      = &(levl[x][y]);
  226.     struct obj *boulder = sobj_at(BOULDER,x,y);
  227.  
  228.     if (dig_pos.x != x || dig_pos.y != y ||
  229.                 !on_level(&dig_level, &u.uz) || dig_down) {
  230.     if (!boulder && (lev->diggable & W_NONDIGGABLE))
  231.         You("hurt your teeth on the hard stone.");
  232.     else {
  233.         dig_down = FALSE;
  234.         dig_pos.x = x;
  235.         dig_pos.y = y;
  236.         assign_level(&dig_level, &u.uz);
  237.         dig_effort = IS_ROCK(lev->typ) ? 30 : 60; /* rock takes more time */
  238.         if (boulder)
  239.         You("start chewing on a boulder.");
  240.         else
  241.         You("start chewing a hole in the %s.",
  242.                     IS_ROCK(lev->typ) ? "rock" : "door");
  243.     }
  244.     return 1;
  245.     } else if ((dig_effort += 30) < 100)  {
  246.     if (flags.verbose)
  247.         You("continue chewing on the %s.", boulder ? "boulder" :
  248.                     (IS_ROCK(lev->typ) ? "rock" : "door"));
  249.     return 1;
  250.     }
  251.  
  252.     if (boulder) {
  253.     You("eat the boulder.");    /* yum */
  254.     delobj(boulder);        /* boulder goes bye-bye */
  255.  
  256.     /*
  257.      *  The location could still block because of
  258.      *      1. More than one boulder
  259.      *      2. Boulder stuck in a wall/stone/door.
  260.      *
  261.      *  [perhaps use does_block() below (from vision.c)]
  262.      */
  263.     if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) {
  264.         block_point(x,y);    /* delobj will unblock the point */
  265.         dig_pos.x = 0;    /* reset dig messages */
  266.         return 1;
  267.     }
  268.     
  269.     } else if (IS_WALL(lev->typ)) {
  270.     You("chew a hole in the wall.");
  271.     if (level.flags.is_maze_lev) {
  272.         lev->typ = ROOM;
  273.     } else if (level.flags.is_cavernous_lev) {
  274.         lev->typ = CORR;
  275.     } else {
  276.         lev->typ = DOOR;
  277.         lev->doormask = D_NODOOR;
  278.     }
  279.     } else if (lev->typ == SDOOR) {
  280.     if (lev->doormask & D_TRAPPED) {
  281.         b_trapped("secret door");
  282.         lev->doormask = D_NODOOR;
  283.     } else {
  284.         You("chew through the secret door.");
  285.         lev->doormask = D_BROKEN;
  286.     }
  287.     lev->typ = DOOR;
  288.  
  289.     } else if (IS_DOOR(lev->typ)) {
  290.     if (lev->doormask & D_TRAPPED) {
  291.         b_trapped("door");
  292.         lev->doormask = D_NODOOR;
  293.     } else {
  294.         You("chew through the door.");
  295.         lev->doormask = D_BROKEN;
  296.     }
  297.  
  298.     } else { /* STONE or SCORR */
  299.     You("chew a passage through the rock.");
  300.     lev->typ = CORR;
  301.     }
  302.  
  303.     unblock_point(x, y);    /* vision */
  304.     newsym(x, y);
  305.     dig_level.dnum = 0;
  306.     dig_level.dlevel = -1;
  307.     return 0;
  308. }
  309. #endif /* POLYSELF */
  310.  
  311. #endif /* OVL2 */
  312. #ifdef OVLB
  313.  
  314. void
  315. movobj(obj, ox, oy)
  316. register struct obj *obj;
  317. register xchar ox, oy;
  318. {
  319.     remove_object(obj);
  320.     newsym(obj->ox, obj->oy);
  321.     place_object(obj, ox, oy);
  322.     newsym(ox, oy);
  323. }
  324.  
  325. #ifdef SINKS
  326. STATIC_OVL void
  327. dosinkfall()
  328. {
  329.     register struct obj *obj;
  330.  
  331. # ifdef POLYSELF
  332.     if (is_floater(uasmon)) {
  333.         You("wobble unsteadily for a moment.");
  334.     } else {
  335. # endif
  336.         You("crash to the floor!");
  337.         losehp((rn1(10, 20 - (int)ACURR(A_CON))),
  338.             "fell onto a sink", NO_KILLER_PREFIX);
  339.         exercise(A_DEX, FALSE);
  340.         for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
  341.             if(obj->oclass == WEAPON_CLASS) {
  342.             You("fell on %s.",doname(obj));
  343.             losehp(rn2(3),"fell onto a sink", NO_KILLER_PREFIX);
  344.             exercise(A_CON, FALSE);
  345.             }
  346. # ifdef POLYSELF
  347.     }
  348. # endif
  349.  
  350.     HLevitation = (HLevitation & ~TIMEOUT) + 1;
  351.     if(uleft && uleft->otyp == RIN_LEVITATION) {
  352.         obj = uleft;
  353.         Ring_off(obj);
  354.         off_msg(obj);
  355.     }
  356.     if(uright && uright->otyp == RIN_LEVITATION) {
  357.         obj = uright;
  358.         Ring_off(obj);
  359.         off_msg(obj);
  360.     }
  361.     if(uarmf && uarmf->otyp == LEVITATION_BOOTS) {
  362.         obj = uarmf;
  363.         (void)Boots_off();
  364.         off_msg(obj);
  365.     }
  366.     HLevitation--;
  367. }
  368. #endif
  369.  
  370. #endif /* OVLB */
  371.  
  372. #ifdef OVLB
  373.  
  374. boolean
  375. may_dig(x,y)
  376. register xchar x,y;
  377. /* intended to be called only on ROCKs */
  378. {
  379. return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE)));
  380. }
  381.  
  382. #endif /* OVLB */
  383. #ifdef OVL1
  384.  
  385. STATIC_OVL boolean
  386. bad_rock(x,y)
  387. register xchar x,y;
  388. {
  389.     return(IS_ROCK(levl[x][y].typ)
  390. #ifdef POLYSELF
  391.             && !passes_walls(uasmon)
  392.             && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y))
  393. #endif
  394.     );
  395. }
  396.  
  397. boolean
  398. invocation_pos(x, y)
  399. xchar x, y;
  400. {
  401.         return(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y);
  402. }
  403.  
  404. #endif /* OVL1 */
  405. #ifdef OVL3
  406.  
  407. void
  408. domove()
  409. {
  410.     register struct monst *mtmp;
  411.     register struct rm *tmpr,*ust;
  412.     register xchar x,y;
  413.     struct trap *trap;
  414.     int wtcap;
  415.     boolean on_ice;
  416.     xchar chainx, chainy, ballx, bally;    /* ball&chain new positions */
  417.     int bc_control;                /* control for ball&chain */
  418.  
  419.     u_wipe_engr(rnd(5));
  420.  
  421.     if(((wtcap = near_capacity()) >= OVERLOADED
  422.         || (wtcap > SLT_ENCUMBER && (u.uhp < 10 && u.uhp != u.uhpmax)))
  423.        && !Is_airlevel(&u.uz)) {
  424.         if(wtcap < OVERLOADED) {
  425.         You("don't have enough stamina to move.");
  426.             exercise(A_CON, FALSE);
  427.         } else
  428.         You("collapse under your load.");
  429.         nomul(0);
  430.         return;
  431.     }
  432.     if(u.uswallow) {
  433.         u.dx = u.dy = 0;
  434.         u.ux = x = u.ustuck->mx;
  435.         u.uy = y = u.ustuck->my;
  436.         mtmp = u.ustuck;
  437.     } else {
  438.         if(Is_airlevel(&u.uz) && rn2(4) && !Levitation
  439. #ifdef POLYSELF
  440.            && !is_flyer(uasmon)
  441. #endif
  442.            ) {
  443.             switch(rn2(3)) {
  444.             case 0:
  445.             You("tumble in place.");
  446.             exercise(A_DEX, FALSE);
  447.             break;
  448.             case 1:
  449.             You("can't control your movements very well."); break;
  450.             case 2:
  451.             pline("It's hard to walk in thin air.");
  452.             exercise(A_DEX, TRUE);
  453.             break;
  454.             }
  455.             return;
  456.         }
  457.  
  458.         /* check slippery ice */
  459.         on_ice = !Levitation && is_ice(u.ux, u.uy);
  460.         if (on_ice) {
  461.             static int skates = 0;
  462.             if (!skates) skates = find_skates();
  463.             if ((uarmf && uarmf->otyp == skates)
  464. #ifdef POLYSELF
  465.             || resists_cold(uasmon) || is_flyer(uasmon)
  466.             || is_floater(uasmon) || is_clinger(uasmon)
  467.             || is_whirly(uasmon)
  468. #endif
  469.                ) on_ice = FALSE;
  470.             else if (!rn2(Cold_resistance ? 3 : 2)) {
  471.             Fumbling |= FROMOUTSIDE;
  472.             if (!(Fumbling & TIMEOUT)) Fumbling += rnd(20);
  473.             }
  474.         }
  475.         if (!on_ice && (Fumbling & FROMOUTSIDE)) {
  476.             Fumbling &= ~FROMOUTSIDE;
  477.             if (!(Fumbling & ~TIMEOUT)) Fumbling = 0;
  478.         }
  479.  
  480.         x = u.ux + u.dx;
  481.         y = u.uy + u.dy;
  482.         if(Stunned || (Confusion && !rn2(5))) {
  483.             register int tries = 0;
  484.  
  485.             do {
  486.                 if(tries++ > 50) {
  487.                     nomul(0);
  488.                     return;
  489.                 }
  490.                 confdir();
  491.                 x = u.ux + u.dx;
  492.                 y = u.uy + u.dy;
  493.             } while(!isok(x, y) || bad_rock(x, y));
  494.         }
  495.         if(!isok(x, y)) {
  496.             nomul(0);
  497.             return;
  498.         }
  499.         if((trap = t_at(x, y)) && trap->tseen) {
  500.             if(flags.run >= 2) {
  501.                 nomul(0);
  502.                 flags.move = 0;
  503.                 return;
  504.             } else
  505.                 nomul(0);
  506.         }
  507.             
  508.         if(u.ustuck && (x != u.ustuck->mx ||
  509.                 y != u.ustuck->my)) {
  510.             if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
  511.             /* perhaps it fled (or was teleported or ... ) */
  512.                 u.ustuck = 0;
  513.             } else {
  514. #ifdef POLYSELF
  515.                 /* If polymorphed into a sticking monster,
  516.                  * u.ustuck means it's stuck to you, not you
  517.                  * to it.
  518.                  */
  519.                 if (sticks(uasmon)) {
  520.                     You("release %s.", mon_nam(u.ustuck));
  521.                     u.ustuck = 0;
  522.                 } else {
  523. #endif
  524.                     You("cannot escape from %s!",
  525.                         mon_nam(u.ustuck));
  526.                     nomul(0);
  527.                     return;
  528. #ifdef POLYSELF
  529.                 }
  530. #endif
  531.             }
  532.         }
  533.         mtmp = m_at(x,y);
  534.         if (mtmp) {
  535.             /* Don't attack if you're running, and can see it */
  536.             if (flags.run &&
  537.                 ((!Blind && mon_visible(mtmp) &&
  538.                   ((mtmp->m_ap_type != M_AP_FURNITURE &&
  539.                 mtmp->m_ap_type != M_AP_OBJECT) ||
  540.                    Protection_from_shape_changers)) ||
  541.                  sensemon(mtmp))) {
  542.                 nomul(0);
  543.                 flags.move = 0;
  544.                 return;
  545.             }
  546.         }
  547.     }
  548.  
  549.     u.ux0 = u.ux;
  550.     u.uy0 = u.uy;
  551.     bhitpos.x = x;
  552.     bhitpos.y = y;
  553.     tmpr = &levl[x][y];
  554.  
  555.     /* attack monster */
  556.     if(mtmp) {
  557.         nomul(0);
  558.         /* only attack if we know it's there */
  559.         /* or if it hides_under, in which case we call attack() to print
  560.          * the Wait! message.
  561.          * This is different from ceiling hiders, who aren't handled in
  562.          * attack().
  563.          */
  564.         if(!mtmp->mundetected || sensemon(mtmp) ||
  565.             (hides_under(mtmp->data) && !is_safepet(mtmp))){
  566.         gethungry();
  567.         if(wtcap >= HVY_ENCUMBER && moves%3) {
  568.             if(u.uhp > 1)
  569.             u.uhp--;
  570.             else {
  571.             pline("You pass out from exertion!");
  572.             exercise(A_CON, FALSE);
  573.             nomul(-10);
  574.             u.usleep = 1;
  575.             }
  576.         }
  577.         if(multi < 0) return;    /* we just fainted */
  578.  
  579.         /* try to attack; note that it might evade */
  580.         /* also, we don't attack tame when _safepet_ */
  581.         if(attack(mtmp)) return;
  582.         }
  583.     }
  584.  
  585.     /* not attacking an animal, so we try to move */
  586. #ifdef POLYSELF
  587.     if(!uasmon->mmove) {
  588.         You("are rooted %s.",
  589.             Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
  590.             "in place" : "to the ground");
  591.         nomul(0);
  592.         return;
  593.     }
  594. #endif
  595.     if(u.utrap) {
  596.         if(u.utraptype == TT_PIT) {
  597.             if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) {
  598.             Your("%s gets stuck in a crevice.", body_part(LEG));
  599.             display_nhwindow(WIN_MESSAGE, FALSE);
  600.             clear_nhwindow(WIN_MESSAGE);
  601.             You("free your %s.", body_part(LEG));
  602.             } else if (!(--u.utrap)) {
  603.             You("crawl to the edge of the pit.");
  604.             fill_pit(u.ux, u.uy);
  605.             vision_full_recalc = 1;    /* vision limits change */
  606.             } else if (flags.verbose) 
  607.             Norep( (Hallucination && !rn2(5)) ?
  608.                 "You've fallen, and you can't get up." :
  609.                 "You are still in a pit." );
  610.         } else if (u.utraptype == TT_LAVA) {
  611.             if(flags.verbose)
  612.                 Norep("You are stuck in the lava.");
  613.             if(!is_lava(x,y)) {
  614.             u.utrap--;
  615.             if((u.utrap & 0xff) == 0) {
  616.                 You("pull yourself to the edge of the lava.");
  617.                 u.utrap = 0;
  618.             }
  619.             }
  620.             u.umoved = TRUE;
  621.         } else if (u.utraptype == TT_WEB) {
  622.             if(--u.utrap) {
  623.             if(flags.verbose)
  624.                 Norep("You are stuck to the web.");
  625.             } else You("disentangle yourself.");
  626.         } else if (u.utraptype == TT_INFLOOR) {
  627.             if(--u.utrap) {
  628.             if(flags.verbose)
  629.                 Norep("You are stuck in the floor.");
  630.             } else You("finally wiggle free.");
  631.         } else {
  632.             if(flags.verbose)
  633.             Norep("You are caught in a bear trap.");
  634.             if((u.dx && u.dy) || !rn2(5)) u.utrap--;
  635.         }
  636.         return;
  637.     }
  638.  
  639.  
  640.     /*
  641.      *  Check for physical obstacles.  First, the place we are going.
  642.      */
  643.     if (IS_ROCK(tmpr->typ)) {
  644.         if (Blind) feel_location(x,y);
  645. #ifdef POLYSELF
  646.         if (passes_walls(uasmon)) {
  647.         ;    /* do nothing */
  648.         } else if (tunnels(uasmon) && !needspick(uasmon)) {
  649.         /* Eat the rock. */
  650.         if (still_chewing(x,y)) return;
  651.         } else {
  652. #endif
  653.         if (Is_stronghold(&u.uz) && is_db_wall(x,y))
  654.             pline("The drawbridge is up!");
  655.         flags.move = 0;
  656.         nomul(0);
  657.         return;
  658. #ifdef POLYSELF
  659.         }
  660. #endif
  661.     } else if (IS_DOOR(tmpr->typ)) {
  662.         if (closed_door(x,y)) {
  663.         if (Blind) feel_location(x,y);
  664. #ifdef POLYSELF
  665.         if (passes_walls(uasmon))
  666.             ;    /* do nothing */
  667.         else if (amorphous(uasmon))
  668.             You("ooze under the door.");
  669.         else if (tunnels(uasmon) && !needspick(uasmon)) {
  670.             /* Eat the door. */
  671.             if (still_chewing(x,y)) return;
  672.         } else {
  673. #endif
  674.             flags.move = 0;
  675.             if (x == u.ux || y == u.uy) {
  676.             if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) {
  677.                 pline("Ouch!  You bump into a door.");
  678.                 exercise(A_DEX, FALSE);
  679.             } else pline("That door is closed.");
  680.             }
  681.             nomul(0);
  682.             return;
  683. #ifdef POLYSELF
  684.         }
  685. #endif
  686.         } else if (u.dx && u.dy
  687. #ifdef POLYSELF
  688.             && !passes_walls(uasmon)
  689. #endif
  690.             && ((tmpr->doormask & ~D_BROKEN)
  691. #ifdef REINCARNATION
  692.                     || Is_rogue_level(&u.uz)
  693. #endif
  694.                     || block_door(x,y))) {
  695.         /* Diagonal moves into a door are not allowed. */
  696.         if (Blind) feel_location(x,y);    /* ?? */
  697.         flags.move = 0;
  698.         nomul(0);
  699.         return;
  700.         }
  701.     }
  702.     if (u.dx && u.dy && bad_rock(u.ux,y) && bad_rock(x,u.uy)) {
  703.         /* Move at a diagonal. */
  704. #ifdef POLYSELF
  705.         if (bigmonst(uasmon)) {
  706.         Your("body is too large to fit through.");
  707.         nomul(0);
  708.         return;
  709.         }
  710. #endif
  711.         if (invent && inv_weight() > -400) {
  712.         You("are carrying too much to get through.");
  713.         nomul(0);
  714.         return;
  715.         }
  716.     }
  717.  
  718.     ust = &levl[u.ux][u.uy];
  719.  
  720.     /* Now see if other things block our way . . */
  721.     if (u.dx && u.dy
  722. #ifdef POLYSELF
  723.              && !passes_walls(uasmon)
  724. #endif
  725.              && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN)
  726. #ifdef REINCARNATION
  727.                  || Is_rogue_level(&u.uz)
  728. #endif
  729.                  || block_entry(x, y))
  730.                  )) {
  731.         /* Can't move at a diagonal out of a doorway with door. */
  732.         flags.move = 0;
  733.         nomul(0);
  734.         return;
  735.     }
  736.  
  737.     if (sobj_at(BOULDER,x,y)
  738. #ifdef POLYSELF
  739.                 && !passes_walls(uasmon)
  740. #endif
  741.                             ) {
  742.         if (!(Blind || Hallucination) && (flags.run >= 2)) {
  743.         nomul(0);
  744.         flags.move = 0;
  745.         return;
  746.         }
  747. #ifdef POLYSELF
  748.         /* tunneling monsters will chew before pushing */
  749.         if (tunnels(uasmon) && !needspick(uasmon)) {
  750.         if (still_chewing(x,y)) return;
  751.         } else
  752. #endif
  753.         if (moverock() < 0) return;
  754.     }
  755.  
  756.     /* OK, it is a legal place to move. */
  757.  
  758.     /* Move ball and chain.  */
  759.     if (Punished)
  760.         if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy))
  761.         return;
  762.  
  763.     /* now move the hero */
  764.     mtmp = m_at(x, y);
  765.     if (u.uinwater) water_friction();
  766.     u.ux += u.dx;
  767.     u.uy += u.dy;
  768.     /* if safepet at destination then move the pet to the hero's
  769.      * previous location using the same conditions as in attack().
  770.      * there are special extenuating circumstances:
  771.      * (1) if the pet dies then your god angers,
  772.      * (2) if the pet gets trapped then your god may disapprove,
  773.      * (3) if the pet was already trapped and you attempt to free it
  774.      * not only do you encounter the trap but you may frighten your
  775.      * pet causing it to go wild!  moral: don't abuse this privilege.
  776.      */
  777.     /* Ceiling-hiding pets are skipped by this section of code, to
  778.      * be caught by the normal falling-monster code.
  779.      */
  780.     if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
  781.         int swap_result;
  782.  
  783.         /* if trapped, there's a chance the pet goes wild */
  784.         if (mtmp->mtrapped && !rn2(4)) {
  785.             pline ("%s suddenly goes wild!",
  786.                mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp));
  787.             mtmp->mtame = mtmp->mpeaceful = mtmp->msleep = 0;
  788.         }
  789.  
  790.         mtmp->mtrapped = 0;
  791.         mtmp->mundetected = 0;
  792.         remove_monster(x, y);
  793.         place_monster(mtmp, u.ux0, u.uy0);
  794.  
  795.         /* check first to see if monster drowned.
  796.          * then check for traps.
  797.          */
  798.         if (minwater(mtmp)) {
  799.             swap_result = 2;
  800.         } else swap_result = mintrap(mtmp);
  801.  
  802.         switch (swap_result) {
  803.         case 0:
  804.             You("%s %s.", mtmp->mtame ? "displaced" : "frightened",
  805.                 mtmp->mnamelth ? NAME(mtmp) : mon_nam(mtmp));
  806.             break;
  807.         case 1:    /* trapped */
  808.         case 3: /* changed levels */
  809.             /* there's already been a trap message, reinforce it */
  810.             pline("Trapping your pet was a selfish move.");
  811.             if (!rn2(4)) {
  812.             pline("You'll pay!");
  813.             adjalign(-5);
  814.             }
  815.             break;
  816.         case 2:
  817.             /* it may have drowned or died.  that's no way to
  818.              * treat a pet!  your god gets angry and complains.
  819.              */
  820.             if (rn2(4)) {
  821.             pline ("%s complains in a booming voice:", u_gname());
  822.             verbalize("Losing your pet like this was a mistake!");
  823.             u.ugangr++ ;
  824.             adjalign(-15);
  825.             }
  826.             break;
  827.         default:
  828.             pline("that's strange, unknown mintrap result!");
  829.             break;
  830.         }
  831.     }
  832.  
  833.     reset_occupations();
  834.     if(flags.run) {
  835.         if(IS_DOOR(tmpr->typ) ||
  836. #ifdef POLYSELF
  837.         (IS_ROCK(tmpr->typ)) ||
  838. #endif
  839.         (xupstair == u.ux && yupstair == u.uy) ||
  840.         (xdnstair == u.ux && ydnstair == u.uy)
  841.         || (sstairs.sx == u.ux && sstairs.sy == u.uy)
  842.         || (xupladder == u.ux && yupladder == u.uy)
  843.         || (xdnladder == u.ux && ydnladder == u.uy)
  844.         || IS_FOUNTAIN(tmpr->typ)
  845.         || IS_THRONE(tmpr->typ)
  846. #ifdef SINKS
  847.         || IS_SINK(tmpr->typ)
  848. #endif
  849.         || IS_ALTAR(tmpr->typ)
  850.         )
  851.             nomul(0);
  852.     }
  853. #ifdef POLYSELF
  854.     if (hides_under(uasmon))
  855.         u.uundetected = OBJ_AT(u.ux, u.uy);
  856.     else if (u.dx || u.dy) { /* piercer */
  857.         if (u.usym == S_MIMIC_DEF)
  858.         u.usym = S_MIMIC;
  859.         u.uundetected = 0;
  860.     }
  861. #endif
  862.  
  863. #ifdef WALKIES
  864.     check_leash(u.ux0,u.uy0);
  865. #endif
  866.     if(u.ux0 != u.ux || u.uy0 != u.uy) {
  867.         u.umoved = TRUE;
  868.         /* Clean old position -- vision_recalc() will print our new one. */
  869.         newsym(u.ux0,u.uy0);
  870.         /* Since the hero has moved, adjust what can be seen/unseen. */
  871.         vision_recalc(1);    /* Do the work now in the recover time. */
  872.  
  873.         /* a special clue-msg when on the Invocation position */
  874.         if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
  875.             register struct obj *otmp;
  876.  
  877.             You("feel a strange vibration under your %s.",
  878.             makeplural(body_part(FOOT)));
  879.  
  880.         for(otmp = invent; otmp; otmp = otmp->nobj) {
  881.                 if(otmp->otyp == CANDELABRUM_OF_INVOCATION &&
  882.                otmp->spe == 7 && otmp->lamplit) {
  883.                       pline("%s glows with a strange light!",
  884.                 The(xname(otmp)));
  885.               break;
  886.                }
  887.             }
  888.         
  889.         }
  890.     }
  891.  
  892.     if (Punished)                /* put back ball and chain */
  893.         move_bc(0,bc_control,ballx,bally,chainx,chainy);
  894.  
  895.     spoteffects();
  896. }
  897.  
  898. #endif /* OVL3 */
  899. #ifdef OVL2
  900.  
  901. void
  902. spoteffects()
  903. {
  904.     register struct trap *trap;
  905.     register struct monst *mtmp;
  906.  
  907.     if(u.uinwater) {
  908.         int was_underwater;
  909.  
  910.         if (!is_pool(u.ux,u.uy)) {
  911.             if (Is_waterlevel(&u.uz))
  912.                 You("pop into an air bubble.");
  913.             else
  914.                 You("are on solid ground again.");
  915.         }
  916.         else if (Is_waterlevel(&u.uz))
  917.             goto stillinwater;
  918.         else if (Levitation || is_floater(uasmon))
  919.             You("pop out of the water like a cork!");
  920.         else if (is_flyer(uasmon))
  921.             You("fly out of the water.");
  922.         else if (Wwalking)
  923.             You("slowly rise above the surface.");
  924.         else
  925.             goto stillinwater;
  926.         was_underwater = Underwater && !Is_waterlevel(&u.uz);
  927.         u.uinwater = 0;        /* leave the water */
  928.         if (was_underwater) {    /* restore vision */
  929.             docrt();
  930.             vision_full_recalc = 1;
  931.         }
  932.     }
  933. stillinwater:;
  934.     if(!Levitation && !u.ustuck
  935. #ifdef POLYSELF
  936.        && !is_flyer(uasmon)
  937. #endif
  938.        ) {
  939.         /* limit recursive calls through teleds() */
  940.         if(is_lava(u.ux,u.uy) && lava_effects())
  941.             return;
  942.         if(is_pool(u.ux,u.uy) && !Wwalking && drown())
  943.             return;
  944.     }
  945.     check_special_room(FALSE);
  946. #ifdef SINKS
  947.     if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
  948.         dosinkfall();
  949. #endif
  950.     if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&
  951.        (!is_pool(u.ux,u.uy) || Underwater))
  952.         pickup(1);
  953.     else read_engr_at(u.ux,u.uy);
  954.     if(trap = t_at(u.ux,u.uy))
  955.         dotrap(trap);    /* fall into pit, arrow trap, etc. */
  956.     if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) {
  957.         mtmp->mundetected = 0;
  958.         switch(mtmp->data->mlet) {
  959.             case S_PIERCER:
  960.             pline("%s suddenly drops from the ceiling!",
  961.                   Amonnam(mtmp));
  962.             if(mtmp->mtame) /* jumps to greet you, not attack */
  963.                 ;
  964.             else if(uarmh)
  965.                 pline("Its blow glances off your helmet.");
  966.             else if (u.uac + 3 <= rnd(20))
  967.                 You("are almost hit by %s!",
  968.                 x_monnam(mtmp, 2, "falling", 1));
  969.             else {
  970.                 int dmg;
  971.                 You("are hit by %s!",
  972.                 x_monnam(mtmp, 2, "falling", 1));
  973.                 dmg = d(4,6);
  974.                 if(Half_physical_damage) dmg = (dmg+1) / 2;
  975.                 mdamageu(mtmp, dmg);
  976.             }
  977.             break;
  978.             default:    /* monster surprises you. */
  979.             if(mtmp->mtame)
  980.                 pline("%s jumps near you from the ceiling.",
  981.                     Amonnam(mtmp));
  982.             else if(mtmp->mpeaceful) {
  983.                 You("surprise %s!",
  984.                     Blind && !sensemon(mtmp) ?
  985.                     "something" : a_monnam(mtmp));
  986.                 mtmp->mpeaceful = 0;
  987.             } else
  988.                 pline("%s attacks you by surprise!",
  989.                     Amonnam(mtmp));
  990.             break;
  991.         }
  992.         mnexto(mtmp); /* have to move the monster */
  993.     }
  994. }
  995.  
  996. STATIC_OVL boolean
  997. monstinroom(mdat,roomno)
  998. struct permonst *mdat;
  999. int roomno;
  1000. {
  1001.     register struct monst *mtmp;
  1002.  
  1003.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1004.         if(mtmp->data == mdat && 
  1005.            index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET))
  1006.             return(TRUE);
  1007.     return(FALSE);
  1008. }
  1009.  
  1010. char *
  1011. in_rooms(x, y, typewanted)
  1012. register xchar x, y;
  1013. register int typewanted;
  1014. {
  1015.     static char buf[5];
  1016.     char rno, *ptr = &buf[4];
  1017.     int typefound, min_x, min_y, max_x, max_y_offset, step;
  1018.     register struct rm *lev;
  1019.  
  1020. #define goodtype(rno) (!typewanted || \
  1021.          ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \
  1022.          ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \
  1023.  
  1024.     switch (rno = levl[x][y].roomno) { 
  1025.         case NO_ROOM:
  1026.             return(ptr);
  1027.         case SHARED:
  1028.             step = 2;
  1029.             break;
  1030.         case SHARED_PLUS:
  1031.             step = 1;
  1032.             break;
  1033.         default:            /* i.e. a regular room # */
  1034.             if (goodtype(rno)) 
  1035.                 *(--ptr) = rno;
  1036.             return(ptr);
  1037.     }
  1038.  
  1039.     min_x = x - 1;
  1040.     max_x = x + 1;
  1041.     if (x < 0)
  1042.         min_x += step;
  1043.     else 
  1044.     if (x >= COLNO)
  1045.         max_x -= step;
  1046.  
  1047.     min_y = y - 1;
  1048.     max_y_offset = 2;
  1049.     if (min_y < 0) {
  1050.         min_y += step;
  1051.         max_y_offset -= step;
  1052.     } else
  1053.     if ((min_y + max_y_offset) >= ROWNO)
  1054.         max_y_offset -= step;
  1055.  
  1056.     for (x = min_x; x <= max_x; x += step) {
  1057.         lev = &levl[x][min_y];
  1058.         y = 0;
  1059.         if (((rno = lev[y].roomno) >= ROOMOFFSET) && 
  1060.             !index(ptr, rno) && goodtype(rno)) 
  1061.             *(--ptr) = rno;
  1062.         y += step;
  1063.         if (y > max_y_offset)
  1064.             continue;
  1065.         if (((rno = lev[y].roomno) >= ROOMOFFSET) && 
  1066.                  !index(ptr, rno) && goodtype(rno))
  1067.             *(--ptr) = rno;
  1068.         y += step;
  1069.         if (y > max_y_offset)
  1070.             continue;
  1071.         if (((rno = lev[y].roomno) >= ROOMOFFSET) && 
  1072.             !index(ptr, rno) && goodtype(rno))
  1073.             *(--ptr) = rno;
  1074.     }
  1075.     return(ptr);
  1076. }
  1077.  
  1078. static void 
  1079. move_update(newlev)
  1080. register boolean newlev;
  1081. {
  1082.     char *ptr1, *ptr2, *ptr3, *ptr4;
  1083.  
  1084.     Strcpy(u.urooms0, u.urooms);
  1085.     Strcpy(u.ushops0, u.ushops);
  1086.     if (newlev) {
  1087.         u.urooms[0] = '\0';
  1088.         u.uentered[0] = '\0';
  1089.         u.ushops[0] = '\0';
  1090.         u.ushops_entered[0] = '\0';
  1091.         Strcpy(u.ushops_left, u.ushops0);
  1092.         return;
  1093.     } 
  1094.     Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0));
  1095.  
  1096.     for (ptr1 = &u.urooms[0], 
  1097.          ptr2 = &u.uentered[0], 
  1098.          ptr3 = &u.ushops[0],
  1099.          ptr4 = &u.ushops_entered[0]; 
  1100.          *ptr1; ptr1++) {
  1101.         if (!index(u.urooms0, *ptr1))
  1102.             *(ptr2++) = *ptr1;    
  1103.         if (IS_SHOP(*ptr1 - ROOMOFFSET)) {
  1104.             *(ptr3++) = *ptr1;
  1105.             if (!index(u.ushops0, *ptr1))
  1106.                 *(ptr4++) = *ptr1;
  1107.         }
  1108.     }
  1109.     *ptr2 = '\0';
  1110.     *ptr3 = '\0';
  1111.     *ptr4 = '\0';
  1112.  
  1113.     /* filter u.ushops0 -> u.ushops_left */
  1114.     for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++)
  1115.         if (!index(u.ushops, *ptr1))
  1116.             *(ptr2++) = *ptr1;
  1117.     *ptr2 = '\0';
  1118. }
  1119.  
  1120. void
  1121. check_special_room(newlev) 
  1122. register boolean newlev;
  1123. {
  1124.     register struct monst *mtmp;
  1125.     char *ptr;
  1126.  
  1127.     move_update(newlev);
  1128.  
  1129.     if (*u.ushops0)
  1130.         u_left_shop(u.ushops_left, newlev);
  1131.  
  1132.     if (!*u.uentered && !*u.ushops_entered) 
  1133.         return;        /* no entrance messages necessary */
  1134.  
  1135.     /* Did we just enter a shop? */
  1136.     if (*u.ushops_entered)
  1137.             u_entered_shop(u.ushops_entered);
  1138.  
  1139.     for (ptr = &u.uentered[0]; *ptr; ptr++) {
  1140.         register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype;
  1141.  
  1142.         /* Did we just enter some other special room? */
  1143.         /* vault.c insists that a vault remain a VAULT,
  1144.          * and temples should remain TEMPLEs,
  1145.          * but everything else gives a message only the first time */
  1146.         if(!newlev) 
  1147.            switch (rt) {
  1148.             case ZOO:
  1149.                pline("Welcome to David's treasure zoo!");
  1150.                 break;
  1151.             case SWAMP:
  1152.                 pline("It %s rather %s down here.",
  1153.                       Blind ? "feels" : "looks",
  1154.                       Blind ? "humid" : "muddy");
  1155.                 break;
  1156.             case COURT:
  1157.             You("enter an opulent throne room!");
  1158.                 break;
  1159.             case MORGUE:
  1160.                 if(midnight())
  1161.                 pline("Run away!  Run away!");
  1162.                 else
  1163.                 You("have an uncanny feeling...");
  1164.                 break;
  1165.             case BEEHIVE:
  1166.                 You("enter a giant beehive!");
  1167.                 break;
  1168. #ifdef ARMY
  1169.             case BARRACKS:
  1170.                 if(monstinroom(&mons[PM_SOLDIER], roomno) ||
  1171.                 monstinroom(&mons[PM_SERGEANT], roomno) ||
  1172.                 monstinroom(&mons[PM_LIEUTENANT], roomno) ||
  1173.                 monstinroom(&mons[PM_CAPTAIN], roomno))
  1174.                     You("enter a military barracks!");
  1175.                 else 
  1176.                 You("enter an abandoned barracks.");
  1177.                 break;
  1178. #endif
  1179.             case DELPHI:
  1180.                 if(monstinroom(&mons[PM_ORACLE], roomno))
  1181.                 verbalize("Hello, %s, welcome to Delphi!", plname);
  1182.                 break;
  1183.             case TEMPLE:
  1184.             intemple(roomno + ROOMOFFSET);
  1185.                 /* fall through */
  1186.             default:
  1187.                 rt = 0;
  1188.             } 
  1189.         else 
  1190.         rt = 0;
  1191.  
  1192.         if(rt != 0) {
  1193.         rooms[roomno].rtype = OROOM;
  1194.         if (!search_special(rt)) {
  1195.             /* No more room of that type */
  1196.             switch(rt) {
  1197.                 case COURT:
  1198.                 level.flags.has_court = 0;
  1199.                 break;
  1200.                 case SWAMP:
  1201.                 level.flags.has_swamp = 0;
  1202.                 break;
  1203.                 case MORGUE:
  1204.                 level.flags.has_morgue = 0;
  1205.                 break;
  1206.                 case ZOO:
  1207.                 level.flags.has_zoo = 0;
  1208.                 break;
  1209. #ifdef ARMY
  1210.                 case BARRACKS:
  1211.                 level.flags.has_barracks = 0;
  1212.                 break;
  1213. #endif
  1214.                 case TEMPLE:
  1215.                 level.flags.has_temple = 0;
  1216.                 break;
  1217.                 case BEEHIVE:
  1218.                 level.flags.has_beehive = 0;
  1219.                 break;
  1220.             }
  1221.         }
  1222.         if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO)
  1223.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1224.                 if(!Stealth && !rn2(3))
  1225.                     mtmp->msleep = 0;
  1226.         }
  1227.     }
  1228.  
  1229.     return;
  1230. }
  1231.  
  1232. #endif /* OVL2 */
  1233. #ifdef OVLB
  1234.  
  1235. int
  1236. dopickup()
  1237. {
  1238.     int count;
  1239.     /* awful kludge to work around parse()'s pre-decrement */
  1240.     count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
  1241.     multi = 0;    /* always reset */
  1242.     /* uswallow case added by GAN 01/29/87 */
  1243.     if(u.uswallow) {
  1244.         if (is_animal(u.ustuck->data)) {
  1245.             You("pick up %s tongue.", 
  1246.                         s_suffix(mon_nam(u.ustuck)));
  1247.             pline("But it's kind of slimy, so you drop it.");
  1248.         } else
  1249.             You("don't %s anything in here to pick up.",
  1250.               Blind ? "feel" : "see");
  1251.         return(1);
  1252.     }
  1253.     if(!OBJ_AT(u.ux, u.uy)) {
  1254.         pline("There is nothing here to pick up.");
  1255.         return(0);
  1256.     }
  1257.     if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
  1258.         You("cannot reach the floor.");
  1259.         return(1);
  1260.     }
  1261.     if(is_pool(u.ux, u.uy)) {
  1262.         if(Wwalking
  1263. #ifdef POLYSELF
  1264.            || is_flyer(uasmon) || is_clinger(uasmon)
  1265. #endif
  1266.            ) {
  1267.             You("cannot dive into the water to pick things up.");
  1268.             return(1);
  1269.         }
  1270.         else if(!Underwater) {
  1271.             You("can't even see the bottom, let alone pick up something.");
  1272.             return(1);
  1273.         }
  1274.     }
  1275.     pickup(-count);
  1276.     return(1);
  1277. }
  1278.  
  1279. #endif /* OVLB */
  1280. #ifdef OVL2
  1281.  
  1282. /* stop running if we see something interesting */
  1283. /* turn around a corner if that is the only way we can proceed */
  1284. /* do not turn left or right twice */
  1285. void
  1286. lookaround()
  1287. {
  1288.     register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9;
  1289.     register int corrct = 0, noturn = 0;
  1290.     register struct monst *mtmp;
  1291.     register struct trap *trap;
  1292.  
  1293. #ifdef POLYSELF
  1294.     /* Grid bugs stop if trying to move diagonal, even if blind.  Maybe */
  1295.     /* they polymorphed while in the middle of a long move. */
  1296.     if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) {
  1297.         nomul(0);
  1298.         return;
  1299.     }
  1300. #endif
  1301.     if(Blind || flags.run == 0) return;
  1302.     for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) {
  1303.         if(!isok(x,y)) continue;
  1304. #ifdef POLYSELF
  1305.     if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue;
  1306. #endif
  1307.     if(x == u.ux && y == u.uy) continue;
  1308.  
  1309.     if((mtmp = m_at(x,y)) &&
  1310.             mtmp->m_ap_type != M_AP_FURNITURE &&
  1311.             mtmp->m_ap_type != M_AP_OBJECT &&
  1312.             (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
  1313.         if((flags.run != 1 && !mtmp->mtame)
  1314.                     || (x == u.ux+u.dx && y == u.uy+u.dy))
  1315.         goto stop;
  1316.     }
  1317.  
  1318.     if (levl[x][y].typ == STONE) continue;
  1319.     if (x == u.ux-u.dx && y == u.uy-u.dy) continue;
  1320.  
  1321.     if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) ||
  1322.         IS_AIR(levl[x][y].typ))
  1323.         continue;
  1324.     else if (closed_door(x,y)) {
  1325.         if(x != u.ux && y != u.uy) continue;
  1326.         if(flags.run != 1) goto stop;
  1327.         goto bcorr;
  1328.     } else if (levl[x][y].typ == CORR) {
  1329. bcorr:
  1330.         if(levl[u.ux][u.uy].typ != ROOM) {
  1331.         if(flags.run == 1 || flags.run == 3) {
  1332.             i = dist2(x,y,u.ux+u.dx,u.uy+u.dy);
  1333.             if(i > 2) continue;
  1334.             if(corrct == 1 && dist2(x,y,x0,y0) != 1)
  1335.             noturn = 1;
  1336.             if(i < i0) {
  1337.             i0 = i;
  1338.             x0 = x;
  1339.             y0 = y;
  1340.             m0 = mtmp ? 1 : 0;
  1341.             }
  1342.         }
  1343.         corrct++;
  1344.         }
  1345.         continue;
  1346.     } else if ((trap = t_at(x,y)) && trap->tseen) {
  1347.         if(flags.run == 1) goto bcorr;    /* if you must */
  1348.         if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  1349.         continue;
  1350.     } else if (is_pool(x,y) || is_lava(x,y)) {
  1351.         /* water and lava only stop you if directly in front, and stop
  1352.          * you even if you are running
  1353.          */
  1354.         if(!Levitation &&
  1355. #ifdef POLYSELF
  1356.             !is_flyer(uasmon) && !is_clinger(uasmon) &&
  1357. #endif
  1358.             /* No Wwalking check; otherwise they'd be able
  1359.              * to test boots by trying to SHIFT-direction
  1360.              * into a pool and seeing if the game allowed it
  1361.              */
  1362.             x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
  1363.         continue;
  1364.     } else {        /* e.g. objects or trap or stairs */
  1365.         if(flags.run == 1) goto bcorr;
  1366.         if(mtmp) continue;        /* d */
  1367.         if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) ||
  1368.            ((y == u.uy - u.dy) && (x != u.ux + u.dx)))
  1369.            continue;
  1370.     }
  1371. stop:
  1372.     nomul(0);
  1373.     return;
  1374.     } /* end for loops */
  1375.  
  1376.     if(corrct > 1 && flags.run == 2) goto stop;
  1377.     if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
  1378.                 (corrct == 1 || (corrct == 2 && i0 == 1))) {
  1379.     /* make sure that we do not turn too far */
  1380.     if(i0 == 2) {
  1381.         if(u.dx == y0-u.uy && u.dy == u.ux-x0)
  1382.         i = 2;        /* straight turn right */
  1383.         else
  1384.         i = -2;        /* straight turn left */
  1385.     } else if(u.dx && u.dy) {
  1386.         if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy))
  1387.         i = -1;        /* half turn left */
  1388.         else
  1389.         i = 1;        /* half turn right */
  1390.     } else {
  1391.         if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy))
  1392.         i = 1;        /* half turn right */
  1393.         else
  1394.         i = -1;        /* half turn left */
  1395.     }
  1396.  
  1397.     i += u.last_str_turn;
  1398.     if(i <= 2 && i >= -2) {
  1399.         u.last_str_turn = i;
  1400.         u.dx = x0-u.ux;
  1401.         u.dy = y0-u.uy;
  1402.     }
  1403.     }
  1404. }
  1405.  
  1406. /* something like lookaround, but we are not running */
  1407. /* react only to monsters that might hit us */
  1408. int
  1409. monster_nearby()
  1410. {
  1411.     register int x,y;
  1412.     register struct monst *mtmp;
  1413.  
  1414.     if(!Blind)
  1415.     for(x = u.ux-1; x <= u.ux+1; x++)
  1416.         for(y = u.uy-1; y <= u.uy+1; y++) {
  1417.         if(!isok(x,y)) continue;
  1418.         if(x == u.ux && y == u.uy) continue;
  1419.         if((mtmp = m_at(x,y)) &&
  1420.            mtmp->m_ap_type != M_AP_FURNITURE &&
  1421.            mtmp->m_ap_type != M_AP_OBJECT &&
  1422.            !mtmp->mpeaceful &&
  1423.            (!is_hider(mtmp->data) || !mtmp->mundetected) &&
  1424.            !noattacks(mtmp->data) &&
  1425.            mtmp->mcanmove && !mtmp->msleep &&  /* aplvax!jcn */
  1426.            (!mtmp->minvis || See_invisible) &&
  1427.            !onscary(u.ux, u.uy, mtmp))
  1428.             return(1);
  1429.     }
  1430.     return(0);
  1431. }
  1432.  
  1433. void
  1434. nomul(nval)
  1435.     register int nval;
  1436. {
  1437.     if(multi < nval) return;    /* This is a bug fix by ab@unido */
  1438.     u.uinvulnerable = FALSE;    /* Kludge to avoid ctrl-C bug -dlc */
  1439.     u.usleep = 0;
  1440.     multi = nval;
  1441.     flags.mv = flags.run = 0;
  1442. }
  1443.  
  1444. #endif /* OVL2 */
  1445. #ifdef OVL1
  1446.  
  1447. void
  1448. losehp(n, knam, k_format)
  1449. register int n;
  1450. register const char *knam;
  1451. boolean k_format;
  1452. {
  1453. #ifdef POLYSELF
  1454.     if (u.mtimedone) {
  1455.         u.mh -= n;
  1456.         if (u.mhmax < u.mh) u.mhmax = u.mh;
  1457.         flags.botl = 1;
  1458.         if (u.mh < 1) rehumanize();
  1459.         return;
  1460.     }
  1461. #endif
  1462.     u.uhp -= n;
  1463.     if(u.uhp > u.uhpmax)
  1464.         u.uhpmax = u.uhp;    /* perhaps n was negative */
  1465.     flags.botl = 1;
  1466.     if(u.uhp < 1) {
  1467.         killer_format = k_format;
  1468.         killer = knam;        /* the thing that killed you */
  1469.         You("die...");
  1470.         done(DIED);
  1471.     } else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){
  1472.         wailmsg = moves;
  1473.         if(index("WEV", pl_character[0])) {
  1474.             if (u.uhp == 1)
  1475.                 pline("%s is about to die.", pl_character);
  1476.             else if (4 <= (!!(HTeleportation & INTRINSIC)) +
  1477.                     (!!(HSee_invisible & INTRINSIC)) +
  1478.                     (!!(HPoison_resistance & INTRINSIC)) +
  1479.                     (!!(HCold_resistance & INTRINSIC)) +
  1480.                     (!!(HShock_resistance & INTRINSIC)) +
  1481.                     (!!(HFire_resistance & INTRINSIC)) +
  1482.                     (!!(HSleep_resistance & INTRINSIC)) +
  1483.                     (!!(HDisint_resistance & INTRINSIC)) +
  1484.                     (!!(HTeleport_control & INTRINSIC)) +
  1485.                     (!!(Stealth & INTRINSIC)) +
  1486.                     (!!(Fast & INTRINSIC)) +
  1487.                     (!!(HInvis & INTRINSIC)))
  1488.                 pline("%s, all your powers will be lost...",
  1489.                     pl_character);
  1490.             else
  1491.                 pline("%s, your life force is running out.",
  1492.                     pl_character);
  1493.         } else {
  1494.             if(u.uhp == 1)
  1495.                 You("hear the wailing of the Banshee...");
  1496.             else
  1497.                 You("hear the howling of the CwnAnnwn...");
  1498.         }
  1499.     }
  1500. }
  1501.  
  1502. int
  1503. weight_cap()
  1504. {
  1505.     register long carrcap;
  1506.  
  1507.     carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50;
  1508. #ifdef POLYSELF
  1509.     if (u.mtimedone) {
  1510.         /* consistent with can_carry() in mon.c */
  1511.         if (u.usym == S_NYMPH)
  1512.                 carrcap = MAX_CARR_CAP;
  1513.         else if (!uasmon->cwt)
  1514.             carrcap = (carrcap * (long)uasmon->msize) / MZ_HUMAN;
  1515.         else if (!strongmonst(uasmon)
  1516.             || (strongmonst(uasmon) && (uasmon->cwt > WT_HUMAN)))
  1517.             carrcap = (carrcap * (long)uasmon->cwt / WT_HUMAN);
  1518.     }
  1519. #endif
  1520.     if(Levitation || Is_airlevel(&u.uz))    /* pugh@cornell */
  1521.         carrcap = MAX_CARR_CAP;
  1522.     else {
  1523.         if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
  1524.         if(Wounded_legs & LEFT_SIDE) carrcap -= 100;
  1525.         if(Wounded_legs & RIGHT_SIDE) carrcap -= 100;
  1526.     }
  1527.     return((int) carrcap);
  1528. }
  1529.  
  1530. /* returns how far beyond the normal capacity the player is currently. */
  1531. /* inv_weight() is negative if the player is below normal capacity. */
  1532. int
  1533. inv_weight()
  1534. {
  1535.     register struct obj *otmp = invent;
  1536. #ifdef LINT    /* long to int conversion */
  1537.     register int wt = 0;
  1538. #else
  1539.     register int wt = (int)((u.ugold + 50L)/100L);
  1540. #endif /* LINT */
  1541.     while(otmp){
  1542. #ifdef POLYSELF
  1543.         if (otmp->otyp != BOULDER || !throws_rocks(uasmon))
  1544. #endif
  1545.             wt += otmp->owt;
  1546.         otmp = otmp->nobj;
  1547.     }
  1548.     return(wt - weight_cap());
  1549. }
  1550.  
  1551. /*
  1552.  * Returns 0 if below normal capacity, or the number of "capacity units"
  1553.  * over the normal capacity the player is loaded.  Max is 5.
  1554.  */
  1555. int
  1556. near_capacity()
  1557. {
  1558.     int cap, wt = inv_weight();
  1559.  
  1560.     if (wt < 0) return UNENCUMBERED;
  1561.     cap = (wt / (weight_cap()/2)) + 1;
  1562.     return min(cap, OVERLOADED);
  1563. }
  1564.  
  1565. int
  1566. max_capacity()
  1567. {
  1568.     return(inv_weight() - (2 * weight_cap()));
  1569. }
  1570.  
  1571. boolean
  1572. check_capacity(str)
  1573. const char *str;
  1574. {
  1575.     if(near_capacity() >= EXT_ENCUMBER) {
  1576.     if(str)
  1577.         pline(str);
  1578.     else
  1579.         You("can't do that while carrying so much stuff.");
  1580.     return 1;
  1581.     }
  1582.     return 0;
  1583. }
  1584.  
  1585. #endif /* OVL1 */
  1586. #ifdef OVLB
  1587.  
  1588. int
  1589. inv_cnt()
  1590. {
  1591.     register struct obj *otmp = invent;
  1592.     register int ct = 0;
  1593.  
  1594.     while(otmp){
  1595.         ct++;
  1596.         otmp = otmp->nobj;
  1597.     }
  1598.     return(ct);
  1599. }
  1600.  
  1601. int
  1602. identify(otmp)        /* also called by newmail() */
  1603.     register struct obj *otmp;
  1604. {
  1605.     makeknown(otmp->otyp);
  1606.     otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
  1607.     prinv(NULL, otmp, 0L);
  1608.     return(1);
  1609. }
  1610.  
  1611. #endif /* OVLB */
  1612.  
  1613. /*hack.c*/
  1614.